//Copyright 2010 Balazs Keri, Imre Keri
//
//This file is part of FireworksCreator.
//
//FireworksCreator is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//FireworksCreator is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with FireworksCreator.  If not, see <http://www.gnu.org/licenses/>.
//
#include <qslider.h>
#include <qpushbutton.h>
#include <qlineedit.h>
#include <qlabel.h>
#include <qvalidator.h>
#include <qboxlayout.h>
#include "playercontrol.h"
//
PlayerControl::PlayerControl(QWidget* parent,Qt::WindowFlags flags)
:
   QWidget(parent,flags),
   playing(false),
   start_time(0),
   stop_time(1000),
   current_time(0),
   looping(false),
   time_slider(new QSlider(Qt::Horizontal)),
   min_edit(new QLineEdit(time_to_str(start_time))),
   max_edit(new QLineEdit(time_to_str(stop_time))),
   time_label(new QLabel(time_to_str(current_time))),
   playing_button(new QPushButton("Play")),
   looping_button(new QPushButton("Loop"))
{
   min_edit->setValidator(new QDoubleValidator(0,60*60*24,3,this));
   max_edit->setValidator(new QDoubleValidator(0,60*60*24,3,this));
   time_slider->setTracking(false);
   time_slider->setFocusPolicy(Qt::NoFocus);
   time_slider->setTickPosition(QSlider::TicksBelow);
   time_slider->setSingleStep(100);
   time_slider->setPageStep(1000);
   time_slider->setRange(start_time,stop_time);
   time_slider->setValue(current_time);
   playing_button->setCheckable(true);
   looping_button->setCheckable(true);
   //
   connect(time_slider,SIGNAL(valueChanged(int)),this,SLOT(current_time_changed(int)));
   connect(min_edit,SIGNAL(editingFinished()),this,SLOT(min_edit_edited()));
   connect(max_edit,SIGNAL(editingFinished()),this,SLOT(max_edit_edited()));
   connect(playing_button,SIGNAL(toggled(bool)),this,SLOT(set_playing(bool)));
   connect(looping_button,SIGNAL(toggled(bool)),this,SLOT(set_looping(bool)));
   //
   QBoxLayout *layout=new QHBoxLayout();
   playing_button->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
   layout->addWidget(playing_button);
   min_edit->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
   layout->addWidget(min_edit);
   time_slider->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
   layout->addWidget(time_slider);
   max_edit->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
   layout->addWidget(max_edit);
   time_label->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
   layout->addWidget(time_label);
   looping_button->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
   layout->addWidget(looping_button);
   setLayout(layout);
}
PlayerControl::~PlayerControl()
{
}
//
void PlayerControl::set_playing(bool playing)
{
   if(playing!=this->playing){
      this->playing=playing;
      playing_button->setChecked(playing);
      emit playing_changed(this->playing);
   }
}
void PlayerControl::set_current_time(unsigned int time)
{
   if(time!=this->current_time){
      this->current_time=time;
      time_slider->setValue(time);
      time_label->setText(time_to_str(time));
      emit current_time_changed(time);
   }
}
void PlayerControl::set_start_time(unsigned int time)
{
   if(time!=start_time){
      min_edit->setText(time_to_str(time));
      min_edit_edited();
   }
}
void PlayerControl::set_stop_time(unsigned int time)
{
   if(time!=stop_time){
      max_edit->setText(time_to_str(time));
      max_edit_edited();
   }
}
void PlayerControl::set_range(unsigned int start_time,unsigned int stop_time)
{
   if(this->start_time!=start_time||this->stop_time!=stop_time){
      this->start_time=start_time;
      this->stop_time=stop_time;
      min_edit->setText(time_to_str(start_time));
      max_edit->setText(time_to_str(stop_time));
      time_slider->setRange(start_time,stop_time);
      emit start_time_changed(start_time);
      emit stop_time_changed(stop_time);
   }
}
void PlayerControl::set_looping(bool looping)
{
   if(looping!=this->looping){
      this->looping=looping;
      looping_button->setChecked(looping);
      emit looping_changed(this->looping);
   }
}
void PlayerControl::current_time_changed(int time)
{
   set_current_time(time);
}
void PlayerControl::min_edit_edited()
{
   unsigned int time=str_to_time(min_edit->displayText());
   if(time!=this->start_time){
      this->start_time=time;
      time_slider->setMinimum(time);
      emit start_time_changed(time);
   }
}
void PlayerControl::max_edit_edited()
{
   unsigned int time=str_to_time(max_edit->displayText());
   if(time!=this->stop_time){
      this->stop_time=time;
      time_slider->setMaximum(time);
      emit stop_time_changed(time);
   }
}
//
bool PlayerControl::is_playing() const
{
   return playing;
}
unsigned int PlayerControl::get_current_time() const
{
   return current_time;
}
unsigned int PlayerControl::get_start_time() const
{
   return start_time;
}
unsigned int PlayerControl::get_stop_time() const
{
   return stop_time;
}
bool PlayerControl::get_looping() const
{
   return looping;
}
//
QString PlayerControl::time_to_str(unsigned int time)
{
   return QString::number(time/1000.0,'f',3);
}
unsigned int PlayerControl::str_to_time(const QString &str)
{
   return str.toDouble()*1000;
}
